home *** CD-ROM | disk | FTP | other *** search
/ Amiga Game-Power / Amiga Game-Power.iso / pd mix ii / access / hddriver / driver / perform_io.c < prev    next >
C/C++ Source or Header  |  1994-05-20  |  4KB  |  207 lines

  1.  
  2. /*
  3.  * Copyright 1987 Alan Kent
  4.  *
  5.  * Permission is granted to redistribute this code as long
  6.  * as this message is retained in the code and the code is
  7.  * not sold without written permission from the author.
  8.  *
  9.  * UUCP: {seismo,hplabs,mcvax,ukc,nttlab}!munnari!goanna.oz!ajk
  10.  * ACSnet: ajk@goanna.oz
  11.  * ARPA: munnari!goanna.oz!ajk@SEISMO.ARPA
  12.  */
  13.  
  14. #include "hd.h"
  15.  
  16.  
  17. void
  18. perform_io ( ior )
  19. struct IOExtHD *ior;
  20. {
  21.     register struct IOStdReq *sior;
  22.     register int i;
  23.     UBYTE *buf;
  24.     struct hd_unit *unit;
  25.     struct posn posn;
  26.     int cmd;
  27.     LONG num_secs;
  28.     char *p;
  29.  
  30.  
  31.     sior = &ior->iohd_TD.iotd_Req;
  32.     unit = (struct hd_unit *) sior->io_Unit;
  33.     sior->io_Error = 0;
  34.     bad_error = 0;
  35.     cmd = sior->io_Command;
  36.  
  37.     if ( cmd & TDF_EXTCOM ) {
  38.         if ( ior->iohd_TD.iotd_Count < CHANGE_COUNT ) {
  39.             sior->io_Error = TDERR_DiskChanged;
  40.             cmd = TD_LASTCOMM + 1;
  41.         }
  42.         else if ( ior->iohd_TD.iotd_SecLabel != NULL ) {
  43.  
  44.             /* I didnt think theses were actually used! */
  45.  
  46.             sior->io_Error = TDERR_NoSecHdr;
  47.             cmd = TD_LASTCOMM + 1;
  48.         }
  49.     }
  50.  
  51.     switch ( cmd ) {
  52.  
  53.     default :
  54.         if ( sior->io_Error == 0 )
  55.             sior->io_Error = IOERR_NOCMD;
  56.         break;
  57.  
  58.     case ETD_MOTOR :
  59.     case TD_MOTOR :
  60.         sior->io_Actual = 1;  /* motor always on - cannot be switched off */
  61.         break;
  62.  
  63.     case TD_REMOVE :
  64.  
  65.         /* cannot remove a harddisk, so not need to install interrupt */
  66.         /* thingo */
  67.  
  68.         break;
  69.  
  70.     case TD_CHANGENUM :
  71.         sior->io_Actual = CHANGE_COUNT;
  72.         break;
  73.  
  74.     case TD_CHANGESTATE :
  75.         sior->io_Actual = 0;
  76.         break;
  77.  
  78.     case TD_PROTSTATUS :
  79.         sior->io_Actual = 0;
  80.         break;
  81.  
  82.     case ETD_CLEAR :
  83.     case CMD_CLEAR :
  84.         clear_all ();
  85.         break;
  86.  
  87.     case ETD_UPDATE :
  88.     case CMD_UPDATE :
  89.         flush_all ();
  90.         if ( sior->io_Error == 0 )
  91.             sior->io_Error = bad_error;
  92.         break;
  93.  
  94.     case ETD_READ :
  95.     case CMD_READ :
  96.         sior->io_Actual = 0;
  97.         if ( calc ( sior , &posn , &num_secs ) ) {
  98.             p = (char *) sior->io_Data;
  99.             while ( num_secs-- > 0 ) {
  100.                 if ( posn.cylinder >= first.cylinders ) {
  101.                     sior->io_Error = TDERR_SeekError;
  102.                     break;
  103.                 }
  104.                 buf = read_cache ( &posn );
  105.                 if ( bad_error != 0  ||  buf == NULL )
  106.                     break;
  107.                 copy_sector ( buf , p );
  108.                 p += HD_SECTOR;
  109.                 sior->io_Actual += HD_SECTOR;
  110.                 next_posn ( &posn );
  111.             }
  112.         }
  113.         if ( sior->io_Error == 0 )
  114.             sior->io_Error = bad_error;
  115.         break;
  116.  
  117.     case ETD_WRITE :
  118.     case CMD_WRITE :
  119.         sior->io_Actual = 0;
  120.         if ( calc ( sior , &posn , &num_secs ) ) {
  121.             p = (char *) sior->io_Data;
  122.             while ( num_secs-- > 0 ) {
  123.                 if ( posn.cylinder >= first.cylinders ) {
  124.                     sior->io_Error = TDERR_SeekError;
  125.                     break;
  126.                 }
  127.                 write_cache ( &posn , p );
  128.                 if ( bad_error != 0 )
  129.                     break;
  130.                 p += HD_SECTOR;
  131.                 sior->io_Actual += HD_SECTOR;
  132.                 next_posn ( &posn );
  133.             }
  134.         }
  135.         if ( sior->io_Error == 0 )
  136.             sior->io_Error = bad_error;
  137.         break;
  138.  
  139.     case TD_SEEK :
  140.         if ( calc ( sior , &posn , &num_secs ) )
  141.             sior->io_Error = wd_seek ( &posn );
  142.         break;
  143.  
  144.     case TD_FORMAT :
  145.         flush_all ();
  146.         clear_all ();
  147.         if ( calc ( sior , &posn , &num_secs ) ) {
  148.             if ( posn.sector != 0 ) {
  149.                 sior->io_Error = TDERR_NotSpecified;
  150.             }
  151.             else {
  152.                 p = (char *) sior->io_Data;
  153.                 while ( num_secs-- > 0 ) {
  154.                     if ( posn.cylinder >= first.cylinders ) {
  155.                         sior->io_Error = TDERR_SeekError;
  156.                         break;
  157.                     }
  158.                     if ( posn.sector == 0 ) {
  159.                         sior->io_Error = wd_format_track ( &posn );
  160.                         if ( sior->io_Error != 0 )
  161.                             break;
  162.                     }
  163.                     write_sector ( &posn , p );
  164.                     if ( bad_error != 0 ) {
  165.                         sior->io_Error = bad_error;
  166.                         break;
  167.                     }
  168.                     p += HD_SECTOR;
  169.                     next_posn ( &posn );
  170.                     if ( posn.sector == 0 )
  171.                         p = (char *) sior->io_Data;
  172.                 }
  173.             }
  174.         }
  175.         break;
  176.  
  177.     case HD_PARK :
  178.         wd_park ();
  179.         break;
  180.  
  181.     case HD_GETINFO :
  182.         ior->iohd_Info = first;
  183.         break;
  184.     }
  185.  
  186.     /* if quick io, dont do a reply */
  187.  
  188.     if ( ( sior->io_Flags & IOF_QUICK ) == 0 )
  189.         ReplyMsg ( ior );
  190. }
  191.  
  192.  
  193. next_posn ( posn )
  194. register struct posn *posn;
  195. {
  196.     posn->block++;
  197.     posn->sector++;
  198.     if ( posn->sector >= first.sectors ) {
  199.         posn->sector = 0;
  200.         posn->surface++;
  201.         if ( posn->surface >= first.heads ) {
  202.             posn->surface = 0;
  203.             posn->cylinder++;
  204.         }
  205.     }
  206. }
  207.